<?php
/**
 * Created by PhpStorm.
 * User: hebidu
 * Date: 15/10/21
 * Time: 16:21
 */

namespace Api\Controller;
use Admin\Api\InternationalAlipayNotifyApi;
use Library\Api\ZjportUploadHisApi;
use Library\Model\ZjportUploadHisModel;
use Shop\Api\OrdersApi;
use Shop\Api\OrdersContactInfoApi;
use Shop\Api\OrdersExpressApi;
use Shop\Api\OrdersInfoViewApi;
use Shop\Api\OrdersItemApi;
use Shop\Api\ProductApi;
use Shop\Api\ProductAttrApi;
use Shop\Api\ProductSkuApi;
use Shop\Model\OrdersModel;

class ZjportController extends  ApiController{

    private $config;
    private $total_price; //个人物品中总计价格

    public function _init(){
        parent::_init();
        $this->config = array(
            'companyCode'=>'341905490',
            'companyName'=>'杭州马班科技有限公司',
            'logisCompanyName'=>'浙江省邮政速递物流有限公司', //物流企业名称
            'logisCompanyCode'=>'3301980101', //物流企业编码
            'payCompanyCode'=>'ZF14021901', //支付公司编码
            'internalAreaCompanyName'=>'杭州汉达国际货运代理有限公司',
            'internalAreaCompanyNo'=>'3301560005',
            'declareCompanyCode'=>'3301280002',
            'declareCompanyName'=>'杭州经济技术开发区报关有限公司',
        );
    }



    /**
     * 个人物品上报单
     */
    public function personal(){
        addLog("Zjport/personal",$_GET,$_POST,"[调试]上报个人物品申报单数据");

        $businessNo = $this->_post("businessNo","","缺失申报流水号!");
        $order_code = $this->_post("order_code",0,"缺失订单编号");

        $destinationPort = $this->_post("destination_port",0,"抵运港必须");
        $declPort = $this->_post("decl_port",0,"申报口岸必须");
        $trafMode = $this->_post("traf_mode",'',"运输方式必须");
        $packNo = $this->_post("pack_no",0,"表体独立包装的数目");
        $iePort = $this->_post("ie_port",'',"进出口岸必须");
        $warpType = $this->_post("warp_type",'');
        $tradeCountry = $this->_post("trade_country",'',"贸易国别(起运地)必须");
        $customsField = $this->_post("customs_field",'',"码头/货场必须");
        $applicationFormNo = $this->_post("application_form_no",'',"申请单编号");
        $importType = $this->_post("importType",'1');
        $declareCompanyType = $this->_post("declareCompanyType",'','申报单位类别（必须）');
//        $businessNo = $this->getBusinessNo();//加+14位企业流水，必须18位
        //1.****** TODO: 以下数据需要取，到哪取？

        $netWeight = ""; //净重，公斤
        //1.************************************
        $express = $this->getExpressInfoForPersonal($order_code);
        $contact = $this->getContactInfo($order_code);

        $pay_code = $this->getPayCode($order_code);


        $consignee = $contact['contactname'];
        $wayBill = $express['expressno'];//不能为空
        $enteringCompanyName = "9999";
        $enteringPerson = "9999";
        $senderCountry = "142";
        $senderName = $this->config['companyName'];
        $worth = "0.0";
        $data = array(
            //JkfSign 信息
            'companyCode'=>$this->config['companyCode'],
            'businessNo'=>$businessNo,
            'businessType'=>'PERSONAL_GOODS_DECLAR',
            'declareType'=>'1',
            'note'=>'',

            'declareCompanyType'=>$declareCompanyType,
            'declareCompanyCode'=>$this->config['declareCompanyCode'],
            'declareCompanyName'=>$this->config['declareCompanyName'],
            //表头
            'accountBookNo' => "",  //可空
            'ieFlag' => "I",
            'preEntryNumber' => $businessNo,
            'importType' => $importType, //"0：直邮进口 1：保税进口

            'inOutDateStr' => "",
            'iePort' => $iePort,    //进出口岸代码
            'destinationPort' => $destinationPort, //指运港（抵运港）
            'trafName'=>'',//运输工具名称
            'voyageNo' => "",// 运输工具航班
            'trafMode' => $trafMode, //运输方式
            'eCommerceCode' => $this->config['companyCode'],
            'eCommerceName' => $this->config['companyName'],
//            'orderNo'=>$order_code,
        //改成pay_code
            'orderNo'=>$pay_code,

            'wayBill'=>$wayBill,
            'tradeCountry' => $tradeCountry,
            'packNo' => $packNo,
            'netWeight'=> $netWeight,
            'warpType' => $warpType,
            'declPort' => $declPort,
            'enteringCompanyName' => $enteringCompanyName,
            'enteringPerson' => $enteringPerson,
            'declarantNo' => "",// 报关员代码
            'customsField' => $customsField,//  码头 / 货场代码
            'consignee' => $consignee, //收件人
            'senderName' => $senderName,//发件人
            'senderCountry' => $senderCountry,
            'senderCity' => "",
            'currCode' => "142",
            'paperType' => "1",
            'paperNumber' => $contact['id_card'],
            'worth' => $worth,
            'internalAreaCompanyName' => $this->config['internalAreaCompanyName'],
            'internalAreaCompanyNo' => $this->config['internalAreaCompanyNo'],
            'applicationFormNo' => $applicationFormNo, //保税进口必须，正式要从仓储取
            'isAuthorize' => "1",
            'remark' => "",
        );


        $details = $this->getPersonalDetail($order_code);
        $data['worth'] = $this->total_price;
        $data = http_build_query($data);

        $data = $data.'&'.$details;

        $return = $this->requestZjport($data,"zjport/personal/upload");

        addLog("Zjport/personal",$return,$data,"请求java接口上报电子口岸返回信息!");

        $this->addToHistory($order_code,$businessNo,$data,$return,ZjportUploadHisModel::UPLOAD_GOODSD_INFO);


        if($return['status']){

            $data = $return['data'];

            if(isset($data['result'])){
                $data =  $data['result'];
            }

            if(is_array($data)){
                if($data['code'] == 0){
                    $this->apiReturnSuc($data['data']);
                }else{
                    $this->apiReturnErr('电子口岸返回信息: '.$data['msg']);
                }
            }else{
                $this->apiReturnErr("请求申报接口的返回结果出错!");
            }

        }else{
            $this->apiReturnErr($return['msg']);
        }

    }




    /**
     * 订单上报
     * order_code , 订单编号
     * total_count , 包裹中商品的总件数
     */
    public function order(){
        addLog("Zjport/order",$_GET,$_POST,"[调试]上报订单数据");
        $order_code = $this->_post("order_code",0,"缺失订单编号");
        $totalCount = $this->_post("total_count",1); '5';//总件数 ，包裹中独立包装的物品总数，不考虑物品计量单位

        $result = apiCall(OrdersInfoViewApi::GET_INFO,array(array('order_code'=>$order_code)));
        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }
        if(is_null($result['info'])){
            $this->apiReturnErr("订单无效(BY101)");
        }
        if(empty($result['info']['pay_code'])){
            $this->apiReturnErr("订单未支付(BY102)");
        }

        $order_info = $result['info'];
        addLog("Zjport/order",$order_info,$order_info,"[调试] 订单数据");
        $taxAmount = $order_info['tax_amount'];

        if($taxAmount < C('DUTY_FREE_PRICE')){
            $taxAmount = 0;
        }

        addLog("Zjport/order",$taxAmount, C('DUTY_FREE_PRICE'),"[调试] 税款");
        $data = array(
            //其它特殊固定的
            'totalCount'=>$totalCount,       //总件数 ，包裹中独立包装的物品总数，不考虑物品计量单位
            'payType'=>'03',                //支付类型 01:银行卡支付 02:余额支付 03:其他

            //jkfSign
            'companyCode'=>$this->config['companyCode'],
//            'businessNo'=>$order_info['order_code'],
            'businessNo'=>$order_info['pay_code'], //
            'businessType'=>'IMPORTORDER',
            'declareType'=>'1',
            'note'=>'',
            //购买人信息

            //head固定部分
            'companyName'=>$this->config['companyName'],
            'eCommerceCode'=>$this->config['companyCode'],
            'eCommerceName'=>$this->config['companyName'],
            'logisCompanyName'=>$this->config['logisCompanyName'], //物流企业名称
            'logisCompanyCode'=>$this->config['logisCompanyCode'], //物流企业编码
            'senderCountry'=>'142',//发件人国别
            'senderName'=>$this->config['companyName'],//发件人名称
            'rate'=>'1',//汇率，人民币填写1
            'ieFlag'=>'I',//进出口 I: 进口
            'paperType'=>'01',//证件类型01:身份证
            'payCompanyCode'=> $this->config['payCompanyCode'],// //支付公司编码
            'zipCode'=>'',  //邮编
            'currCode'=>'142', //货币编码
            'userProcotol'=>'本人承诺所购买商品系个人合理自用，现委托商家代理申报、代缴税款等通关事宜，本人保证遵守《海关法》和国家相关法律法规，保证所提供的身份信息和收货信息真实完整，无侵犯他人权益的行为，以上委托关系系如实填写，本人愿意接受海关、检验检疫机构及其他监管部门的监管，并承担相应法律责任.',

            //订单中取得
//            'orderNo'=>$order_info['order_code'],      //订单编号
            'orderNo'=>$order_info['pay_code'],      //订单编号
            'taxAmount'=>$taxAmount,         //订单税款
            'feeAmount'=>$order_info['post_price'],              //运费

            //购买人信息
            'id'=>$order_info['uid'],
            'name'=>$order_info['contactname'],
            'email'=>$order_info['email'],
            'telNumber'=>$order_info['mobile'],
            'address'=>$order_info['country'].$order_info['province'].$order_info['city'].$order_info['area'].$order_info['detailinfo'],
            'paperNumber'=>$order_info['id_card'],
        );

        $data = array_merge($data,$this->getExpressInfo($order_info));


        $result = $this->checkData($data);

        if(!empty($result)){
            $this->apiReturnErr($result);
        }

        $details = $this->getOrderDetail($order_info['order_code']);

        $data['goodsAmount'] = $this->total_price;

        $data = http_build_query($data);

        $data = $data.'&'.$details;

        $return = $this->requestZjport($data,'zjport/order/upload');

        addLog("Zjport/order",$return,$data,"请求java接口上报电子口岸返回信息!");

        $this->addToHistory($order_code,$order_code,$data,$return,ZjportUploadHisModel::UPLOAD_ORDER_INFO);

        if($return['status']){

            $data = $return['data'];

            if(isset($data['result'])){
                $data =  $data['result'];
            }

            if(is_array($data)){
                if($data['code'] == 0){
                     $this->apiReturnSuc($data['data']);
                }else{
                    $this->apiReturnErr('电子口岸返回信息: '.$data['msg']);
                }
            }else{
                $this->apiReturnErr("请求申报接口的返回结果出错!");
            }

        }else{
            $this->apiReturnErr($return['msg']);
        }
    }












    //==================== 私有方法 ================================

    private function getPayCode($order_code){
        $result = apiCall(OrdersApi::GET_INFO,array(array('order_code'=>$order_code)));

        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }

        if(is_null($result['info'])){
            $this->apiReturnErr("支付信息获取失败!");
        }

        return $result['info']['pay_code'];
    }

    private function getContactInfo($order_code){

        $result = apiCall(OrdersContactInfoApi::GET_INFO,array(array('order_code'=>$order_code)));

        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }

        if(is_null($result['info'])){
            $this->apiReturnErr("订单编号:".$order_code.",收货人信息获取失败!");
        }
        return $result['info'];
    }

    /**
     * 获取物流相关信息－个人物品申报单
     * @param $order_code
     * @return mixed
     */
    private function getExpressInfoForPersonal($order_code){

        $result = apiCall(OrdersExpressApi::GET_INFO,array(array('order_code'=>$order_code)));

        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }

        if(is_null($result['info'])){
            $this->apiReturnErr("订单尚未发货,无法申报!");
        }

        $express = $result['info'];
        return $express;
    }

    /**
     * 纪录日志
     * @param $order_code
     * @param $serial_no
     * @param $upload_content
     * @param string $result
     */
    private function addToHistory($order_code,$serial_no,$upload_content,$result="",$type){
        if(empty($upload_content)){
            $upload_content = "";
        }

        if(empty($result)){
            $result = "";
        }

        if(is_array($upload_content)){
            $upload_content = json_encode($upload_content);
        }
        if(is_array($result)){
            $result = json_encode($result);
        }

        $entity = array(
            'order_code'=>$order_code,
            'upload_time'=>NOW_TIME,
            'serial_no'=>$serial_no,
            'asyn_result'=>'',
            'result'=>$result,
            'upload_content'=>$upload_content,
            'type'=>$type,
        );

        $result = apiCall(ZjportUploadHisApi::ADD,array($entity));

    }

    /**
     * 获取物流相关信息
     * @param $order
     * @return array
     */
    private function  getExpressInfo($order){

        $map = array(
            'order_code'=>$order['order_code'],
        );
        //1. 获取支付信息，并校验部分数据

        $payInfo = array();
        if($order['pay_status'] == OrdersModel::ORDER_PAID){

            if($order['pay_type'] == OrdersModel::PAY_TYPE_ALIPAY){
                $result = apiCall(InternationalAlipayNotifyApi::GET_INFO,array(array('out_trade_no'=>$order['pay_code'])));
            }else{
                $this->apiReturnErr("不支持的支付方式!".$order['pay_type']);
            }

            if(!$result['status']){
                $this->apiReturnErr($result['info']);
            }



            if(is_null($result['info'])){
                $this->apiReturnErr("订单支付信息获取失败,无法申报!");
            }

            $payInfo = $result['info'];

        }else{
            $this->apiReturnErr("订单尚未支付,无法申报!");
        }

        if(!($payInfo['trade_status'] == 'TRADE_FINISHED')){
            $this->apiReturnErr("订单支付失败,无法申报!");
        }

        //2. 获取物流信息，并校验相关信息

        $result = apiCall(OrdersExpressApi::GET_INFO,array($map));


        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }

        if(is_null($result['info'])){
            $this->apiReturnErr("订单尚未发货,无法申报!");
        }

        $express = $result['info'];

        $tradeTime = intval($payInfo['notify_time']);

        $data  = array(
            'walBills'=>$express['expressno'],  //物流单号，逗号分开，多个
            'payNumber'=>$payInfo['trade_no'],  //支付单号
            'totalAmount'=>$payInfo['total_fee'], //支付总额
            'tradeTime'=>$tradeTime, //成交时间
        );

        return $data;
    }

    /**
     * 获取订单详情信息
     * @param $order_code
     * @return array
     */
    private function getOrderDetail($order_code){

        $map = array(
            'order_code'=>$order_code,
        );
        $result = apiCall(OrdersItemApi::QUERY_NO_PAGING,array($map));

        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }
        if(is_null($result['info'])){
            $this->apiReturnErr("没有商品，不能发送申报单");
        }

        $items = $result['info'];

        $query_str = "nostr=1";

        foreach($items as $key=>$vo){
            $name = empty($vo['name'])?"未知商品":$vo['name'];
            $query_str = $query_str.'&goodsName[]='.$name.'&codeTs[]='.$vo['dt_tariff_code'].'&goodsModel[]='.$vo['sku_desc'];
            $query_str = $query_str.'&originCountry[]='.$vo['dt_origin_country'].'&unitPrice[]='.$vo['price'].'&goodsCount[]='.$vo['count'];
            $query_str = $query_str.'&goodsUnit[]='.$vo['dt_goods_unit'].'&grossWeight[]='.$vo['weight'];

            $this->total_price += ($vo['price']*$vo['count']);
        }
        $this->total_price = number_format($this->total_price,2);
        return $query_str;
    }


    private function getPersonalDetail($order_code){

        $map = array(
            'order_code'=>$order_code,
        );

        $result = apiCall(OrdersItemApi::QUERY_NO_PAGING,array($map));

        if(!$result['status']){
            $this->apiReturnErr($result['info']);
        }

        if(is_null($result['info'])){
            $this->apiReturnErr("没有商品，不能发送申报单");
        }



        $items = $result['info'];

        $query_str = "nostr=1";
        $this->total_price = 0;
        $mainGName = "主要货物";
        $grossWeight = 0;//毛重

        foreach($items as $key=>$vo){
            //新增，获取商品属性
            $result = apiCall(ProductAttrApi::GET_INFO,array(array('pid'=>$vo['p_id'])));
            if(!$result['status'] || empty($result['info'])){
                $this->apiReturnErr("商品属性信息获取失败!");
            }
            $attr_entity = $result['info'];
            if($attr_entity['weight'] <= 0){
                $this->apiReturnErr("商品ID:".$vo['p_id']."的重量必须大于0!");
            }
            $vo['weight'] = $attr_entity['weight'];

            $this->total_price = $this->total_price + $vo['price']*$vo['count'];
            $name = empty($vo['name'])?"未知商品":$vo['name'];
            $mainGName = $name;
            $grossWeight = $vo['weight'] * $vo['count'];
            $product_code = $this->getProductCode($vo);
            $sku_desc = empty($vo['sku_desc'])?"无规格":$vo['sku_desc'];
            $item_total_price = $vo['price'] * $vo['count'];
            $query_str = $query_str.'&goodsItemNo[]='.$product_code;//商品货号
            $query_str = $query_str.'&goodsName[]='.$name.'&codeTs[]='.$vo['dt_tariff_code'].'&goodsModel[]='.$sku_desc;
            $query_str = $query_str.'&tradeCurr[]='.'142';//成交币值
            $query_str = $query_str.'&declPrice[]='.$vo['price'];//商品货号
            $query_str = $query_str.'&tradeTotal[]='.$item_total_price.'&declTotalPrice[]='.$item_total_price;//
            $query_str = $query_str.'&useTo[]=';//
            $query_str = $query_str.'&productRecordNo[]=';//
            $query_str = $query_str.'&declareCount[]='.$vo['count'];//
            $query_str = $query_str.'&goodsUnit[]='.$vo['dt_goods_unit'].'&goodsGrossWeight[]='.$vo['weight'];
            $query_str = $query_str.'&secondUnit[]='.'&secondCount[]=';//
            $query_str = $query_str.'&firstUnit[]='.$vo['dt_goods_unit'].'&firstCount[]='.$vo['count'];//
            $query_str = $query_str.'&webSite[]='.C('SITE_URL')."/Shop/Product/detail/id/".$vo['p_id'];//
            $query_str = $query_str.'&originCountry[]='.$vo['dt_origin_country'].'&unitPrice[]='.$vo['price'].'&goodsCount[]='.$vo['count'];
            if(floatval($vo['weight']) <= 0){
                $this->apiReturnErr("商品毛重必须大于0！");
            }
        }

        $grossWeight = round($grossWeight / 1000,2);
        return $query_str.'&mainGName='.$mainGName.'&grossWeight='.$grossWeight;
    }

    private function getProductCode($vo){
        $p_id = $vo['p_id'];

        $sku_id = $vo['sku_id'];
        $map = array(
        );
        $product_code  = 0;
        if(empty($sku_id)){
            $map['id'] = $p_id;
            //无规格
            $result = apiCall(ProductApi::GET_INFO,array($map));

        }else{
            //有规格
            $map['product_id'] = $p_id;
            $map['sku_id'] = $sku_id;
            $result  = apiCall(ProductSkuApi::GET_INFO,array($map));
        }

        if($result['status'] && is_array($result['info'])){
            $product_code = $result['info']['product_code'];
        }

        return $product_code;
    }




    private function checkData($data){

        return false;
    }

    /**
     * 请求电子口岸接口
     * @author 老胖子-何必都 <hebiduhebi@126.com>
     * @param $data
     * @return array
     */
    private function requestZjport($data,$api_method){
        $url = ZJPORT_API_URL.$api_method;
        if(is_array($data)){
            $data = http_build_query($data);
        }
        $result = $this->curlPost($url,$data);
        return $result;
    }
    protected function curlPost($url, $data) {

        $ch = curl_init();
        $header = array('Accept-Charset'=>"utf-8");

        curl_setopt($ch,CURLOPT_TIMEOUT,60);//30秒超时
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');

        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, ($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $tmpInfo = curl_exec($ch);
        $error = curl_errno($ch);


        if ($error) {
            $error = $this->getCurlErrMsg($error);
            return array('status' => false, 'msg' => $error,'data'=>'');
        } else {
            $js = json_decode($tmpInfo,true);

            return array('status' => true,'msg'=>'处理成功', 'data' => $js);
        }
    }

    protected function curlGet($url) {
        $ch = curl_init();
        $header = "Accept-Charset: utf-8";
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');

        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($ch);
        return $temp;
    }

    private function getCurlErrMsg($error_no){

        $error_no = strval($error_no);
        if(isset(ZjportController::$error_arr[$error_no])){
            return ZjportController::$error_arr[$error_no];
        }
        return "未知错误!";
    }

    public static $error_arr = array(
        '1'=>'您传送给 libcurl 的网址使用了此 libcurl 不支持的协议。 可能是您没有使用的编译时选项造成了这种情况（可能是协议字符串拼写有误，或没有指定协议 libcurl 代码）。',
        '2'=>'非常早期的初始化代码失败。 可能是内部错误或问题。',
        '3'=>'网址格式不正确。',
        '5'=>'无法解析代理服务器。 指定的代理服务器主机无法解析。',
        '6'=>'无法解析主机。 指定的远程主机无法解析。',
        '7'=>'无法通过 connect() 连接至主机或代理服务器。',
        '8'=>'在连接到 FTP 服务器后，libcurl 需要收到特定的回复。 此错误代码表示收到了不正常或不正确的回复。 指定的远程服务器可能不是正确的 FTP 服务器。',
        '9'=>' 我们无法访问网址中指定的资源。 对于 FTP，如果尝试更改为远程目录，就会发生这种情况。',
        '11'=>'在将 FTP 密码发送到服务器后，libcurl 需要收到正确的回复。 此错误代码表示返回的是意外的代码。',
        '13'=>'libcurl 无法从服务器端收到有用的结果，作为对 PASV 或 EPSV 命令的响应。 服务器有问题。',
        '14'=>'FTP 服务器返回 227 行作为对 PASV 命令的响应。如果 libcurl 无法解析此行，就会返回此代码。',
        '15'=>'在查找用于新连接的主机时出现内部错误。',
        '17'=>'在尝试将传输模式设置为二进制或 ascii 时发生错误。',
        '18'=>'文件传输尺寸小于或大于预期。当服务器先报告了一个预期的传输尺寸，然后所传送的数据与先前指定尺寸不相符时，就会发生此错误。',
        '19'=>'RETR 命令收到了不正常的回复，或完成的传输尺寸为零字节。',
        '21'=>'在向远程服务器发送自定义 “QUOTE” 命令时，其中一个命令返回的错误代码为 400 或更大的数字（对于 FTP），或以其他方式表明命令无法成功完成。',
        '22'=>'如果 CURLOPT_FAILONERROR 设置为 TRUE，且 HTTP 服务器返回 >= 400 的错误代码，就会返回此代码。 （此错误代码以前又称为 CURLE_HTTP_NOT_FOUND。）',
        '23'=>'在向本地文件写入所收到的数据时发生错误，或由写入回调 (write callback) 向 libcurl 返回了一个错误。',
        '25'=> '无法开始上传。 对于 FTP，服务器通常会拒绝执行 STOR 命令。错误缓冲区通常会提供服务器对此问题的说明。 （此错误代码以前又称为 CURLE_FTP_COULDNT_STOR_FILE。）',
        '26'=> '读取本地文件时遇到问题，或由读取回调 (read callback) 返回了一个错误。',
        '27'=> '内存分配请求失败。此错误比较严重，若发生此错误，则表明出现了非常严重的问题。',
        '28'=> ' 操作超时。 已达到根据相应情况指定的超时时间。 请注意： 自 Urchin 6.6.0.2 开始，超时时间可以自行更改。 要指定远程日志下载超时，请打开 urchin.conf 文件，取消以下行的注释标记：',
        '30'=>' FTP PORT 命令返回错误。 在没有为 libcurl 指定适当的地址使用时，最有可能发生此问题。 请参阅 CURLOPT_FTPPORT。',
        '31'=>' FTP REST 命令返回错误。如果服务器正常，则应当不会发生这种情况。',
        '33'=>' 服务器不支持或不接受范围请求。',
        '34'=>' 此问题比较少见，主要由内部混乱引发。',
        '35'=>' 同时使用 SSL/TLS 时可能会发生此错误。您可以访问错误缓冲区查看相应信息，其中会对此问题进行更详细的介绍。可能是证书（文件格式、路径、许可）、密码及其他因素导致了此问题。',
        '36'=>' 尝试恢复超过文件大小限制的 FTP 连接。',
        '37'=>' 无法打开 FILE:// 路径下的文件。原因很可能是文件路径无法识别现有文件。 建议您检查文件的访问权限。',
        '38'=>' LDAP 无法绑定。LDAP 绑定操作失败。',
        '39'=>' LDAP 搜索无法进行。',
        '41'=>' 找不到函数。 找不到必要的 zlib 函数。',
        '42'=>' 由回调中止。 回调向 libcurl 返回了 “abort”。',
        '43'=>' 内部错误。 使用了不正确的参数调用函数。',
        '45'=>' 界面错误。 指定的外部界面无法使用。 请通过 CURLOPT_INTERFACE 设置要使用哪个界面来处理外部连接的来源 IP 地址。 （此错误代码以前又称为 CURLE_HTTP_PORT_FAILED。）',
        '47'=>' 重定向过多。 进行重定向时，libcurl 达到了网页点击上限。请使用 CURLOPT_MAXREDIRS 设置上限。',
        '48'=>' 无法识别以 CURLOPT_TELNETOPTIONS 设置的选项。 请参阅相关文档。',
        '49'=>' telnet 选项字符串的格式不正确。',
        '51'=>' 远程服务器的 SSL 证书或 SSH md5 指纹不正确。',
        '52'=>' 服务器未返回任何数据，在相应情况下，未返回任何数据就属于出现错误。',
        '53'=>' 找不到指定的加密引擎。',
        '54'=>' 无法将选定的 SSL 加密引擎设为默认选项。',
        '55'=>' 无法发送网络数据。',
        '56'=>' 接收网络数据失败。',
        '58'=>' 本地客户端证书有问题',
        '59'=>' 无法使用指定的密钥',
        '60'=>' 无法使用已知的 CA 证书验证对等证书',
        '61'=>' 无法识别传输编码',
        '62'=>' LDAP 网址无效',
        '63'=>' 超过了文件大小上限',
        '64'=>' 请求的 FTP SSL 级别失败',
        '65'=>' 进行发送操作时，curl 必须回转数据以便重新传输，但回转操作未能成功',
        '66'=>' SSL 引擎初始化失败',
        '67'=>' 远程服务器拒绝 curl 登录（7.13.1 新增功能）',
        '68'=>' 在 TFTP 服务器上找不到文件',
        '69'=>' 在 TFTP 服务器上遇到权限问题',
        '70'=>' 服务器磁盘空间不足',
        '71'=>' TFTP 操作非法',
        '72'=>' TFTP 传输 ID 未知',
        '73'=>' 文件已存在，无法覆盖',
        '74'=>' 运行正常的 TFTP 服务器不会返回此错误',
        '75'=>' 字符转换失败',
        '76'=>' 调用方必须注册转换回调',
        '77'=>' 读取 SSL CA 证书时遇到问题（可能是路径错误或访问权限问题）',
        '78'=>' 网址中引用的资源不存在',
        '79'=>' SSH 会话中发生无法识别的错误',
        '80'=>' 无法终止 SSL 连接',
    );


}